import Vue from 'vue'
import axios from 'axios'
import { Message } from 'element-ui'
import router from '@/router'
import store from '@/store'
import i18n from '@/components/i18n'

export const baseURL = process.env.USE_PROXY ? '' : process.env.API

Vue.$message = Message

// 国际化语言包
const LANGUAGE_KEY = localStorage.getItem('LANGUAGE_KEY')
const LANG_LIST = {
  'zh-CN': 'zn'
}

/**
 * 设置请求header
 * @param {Object} headers
 */
const setHeader = (headers) => {
  for (const key in headers) {
    axios.defaults.headers[key] = headers[key]
  }
}

// 1. axios基础配置
axios.defaults.headers['Content-Type'] = 'application/json'
axios.defaults.headers['lang'] = LANG_LIST[LANGUAGE_KEY] ? LANG_LIST[LANGUAGE_KEY] : LANGUAGE_KEY
axios.defaults.timeout = '60000'

// request拦截器
axios.interceptors.request.use((config) => {
  // 添加token
  if (store.getters.GET_TOKEN) {
    config.headers.Authorization = store.getters.GET_TOKEN
  }
  return config
}, (error) => {
  return Promise.reject(error)
})

// responese拦截器
axios.interceptors.response.use((res) => {
  if (res.data.code === 0) { // 成功
    return res
  } else if (res.data.code === 102) { // 登录失效
    Vue.$message.error(i18n.tc('message.Login is invalid Please log in again'))
    router.replace('/login')
  } else {
    Vue.$message.error(res.data.message)
    return Promise.reject(res)
  }
}, (error) => {
  // 提示错误类型
  if (error.toString().indexOf('Network Error') !== -1) {
    Vue.$message.error('Network Error')
  } else if (error.response > 500 && error.response.status) {
    Vue.$message.error(i18n.tc('message.Server Exception'))
  } else if (error.response && error.response.status === 404) {
    Vue.$message.error(i18n.tc('message.Request address error'))
  } else if (error.message && error.message.indexOf('timeout') !== -1) {
    Vue.$message.error(i18n.tc('message.The request timeout'))
  } else {
    Vue.$message.error(error.toString())
  }
  return Promise.reject(error)
})

// 2. 请求配置
// 2.1 GET 请求
export const methodGet = (url, params, headers) => {
  return new Promise((resolve, reject) => {
    setHeader(headers)
    axios.get(url, { params }).then((response) => {
      if (response && response.data) {
        resolve(response.data)
      }
    }).catch((error) => {
      reject(error)
    })
  })
}

// 2.2 POST请求
export const methodPost = (url, params, headers) => {
  return new Promise((resolve, reject) => {
    setHeader(headers)
    axios.post(url, params).then((response) => {
      if (response && response.data) {
        resolve(response.data)
      }
    }).catch((error) => {
      reject(error)
    })
  })
}

// 2.3 PUT请求
export const methodPut = (url, params, headers) => {
  return new Promise((resolve, reject) => {
    setHeader(headers)
    axios.put(url, params).then((response) => {
      if (response && response.data) {
        resolve(response.data)
      }
    }).catch((error) => {
      reject(error)
    })
  })
}

// 3 下载
// 3.1 POST下载请求
export const downloadPost = (url, params) => {
  return new Promise((resolve, reject) => {
    axios.post(url, params, { responseType: 'arraybuffer' }).then((response) => {
      try {
        const fileName = decodeURIComponent(response.headers['content-disposition'].replace(/.+filename=(.+)/g, '$1'))
        resolve({ data: response.data, name: fileName })
      } catch (e) {
        Vue.$message.error(e)
      }
    }).catch((error) => {
      reject(error)
    })
  })
}

// 3.2 文件流下载到本地
export const downloadFile = (url, params) => {
  downloadPost(url, params).then((res) => {
    const fileUrl = window.URL.createObjectURL(new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' }))
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = fileUrl
    link.setAttribute('download', res.name)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(fileUrl)
  })
}
